<template>
  <tr
    v-for="key in Object.keys(selectedMaterial)"
    class="prop-row"
    :key="key"
    v-show="getParamOpenStatus(key)"
  >
    <td :class="setParamClass(key)">
      <img
        v-if="props.selectedMaterial[key]?.hasChild === true"
        :class="{ icon: true, rotate: closeStatus(key) }"
        src="../../assets/down_triangle.svg"
        v-on:click="handleOpensub(key)"
      />
      <div v-else class="icon" />
      {{ formatTitle(key) }}
    </td>
    <td>
      <div
        v-if="getObject(key)?.type === GRID_TYPE.DISABLED"
        style="color: #91989a"
        class="disabled"
      >
        {{ MaterialName(key) }}
      </div>
      <Button
        v-else-if="getObject(key)?.type === GRID_TYPE.BUTTON"
        size="small"
        @click="handleButtonClick(key)"
      >
        {{ MaterialName(key) }}
      </Button>
      <input
        v-else-if="
          getObject(key) !== undefined &&
          getObject(key).type === GRID_TYPE.INPUT
        "
        :type="getInputType(key, getObject(key).type)"
        :value="MaterialName(key)"
        @change="(e) => handleChangeParam(e.target.value, key)"
        @keyup.enter="showMatNameLabelHandler(key)"
        @dblclick="changeMatNameHandler(key)"
        @blur="showMatNameLabelHandler(key)"
        style="width: 100%; text-align: left; height: 35px"
      />
      <input
        v-else-if="
          getObject(key) !== undefined && getObject(key).type === GRID_TYPE.INT
        "
        :type="getInputType(key, getObject(key).type)"
        :value="MaterialName(key)"
        @change="(e) => handleChangeParam(parseFloat(e.target.value), key)"
        @keyup.enter="showMatNameLabelHandler(key)"
        @dblclick="changeMatNameHandler(key)"
        @blur="showMatNameLabelHandler(key)"
        step="1"
        style="width: 100%; text-align: left; height: 35px"
      />
      <input
        v-else-if="
          getObject(key) !== undefined &&
          getObject(key).type === GRID_TYPE.FLOAT
        "
        :type="getInputType(key, getObject(key).type)"
        @change="(e) => handleChangeParam(parseFloat(e.target.value), key)"
        @keyup.enter="showMatNameLabelHandler(key)"
        @dblclick="changeMatNameHandler(key)"
        @blur="showMatNameLabelHandler(key)"
        :value="MaterialName(key)"
        step="0.01"
        style="width: 100%; text-align: left; height: 35px"
      />
      <Select
        v-else-if="
          getObject(key) !== undefined &&
          getObject(key).type === GRID_TYPE.SELECT
        "
        :value="MaterialName(key)"
        :options="getOptions(key)"
        @change="(e) => handleChangeParam(e, key)"
      />
      <div
        class="color-box"
        v-else-if="
          getObject(key) !== undefined &&
          getObject(key).type === GRID_TYPE.COLOR
        "
        @click="setColor(gyColor2rgb255str(MaterialName(key)))"
        :style="`background-color: ${gyColor2rgb255str(MaterialName(key))};
                          width: 16px;
                          height: 16px;
                          margin-left: 15px;
                          cursor: pointer;
                        `"
      ></div>
      <Checkbox
        v-else-if="
          getObject(key) !== undefined &&
          getObject(key).type === GRID_TYPE.CHECKBOX
        "
        :checked="MaterialName(key)"
        @change="(e) => handleChangeParam(e, key)"
        type="checkbox"
      />
      <div v-else>
        {{ MaterialName(key) }}
      </div>
    </td>
  </tr>
  <ColorModalVue
    v-if="showColorPicker"
    @emitColor="getChildColor"
    :color-in="itemColor"
  ></ColorModalVue>
</template>
<script setup lang="ts">
import { ref, defineProps, defineEmits } from "vue";
import { gyColor2rgb255str } from "../sidebar/color";
import { Select, Checkbox } from "cax-ui";
import { GRID_TYPE } from "../sidebar/constants";
import { useCoreStore } from "@/UI/store";
import ColorModalVue from "../../views/modal/ColorModal.vue";
import type { Color } from "cax-ui";
import { Button } from "cax-ui";

const props = defineProps({
  selectedMaterial: {
    type: Object,
    default: () => {
      return { name: "材料A", id: 957, is_selected: false };
    },
  },
  editorProps: {
    type: Object as () => Record<string, any>,
    default: () => ({}), // 默认值为空对象
  },
  propsInitial: {
    type: Object as () => Record<string, any>,
    default: () => ({}), // 默认值为空对象
  },
  originalMaterial: {
    type: Object,
    default: () => {
      return { name: "材料A", id: 957, is_selected: false };
    },
  },
  materialListIn: {
    type: Array,
    default: () => {
      return [];
    },
  },
});
// eslint-disable-next-line vue/no-setup-props-destructure
const showMatNameLabel = ref(false);
const showedMatNameKey = ref<null | string>(null);
const openedSubParams = ref<string[]>([]);
const previousType = ref(props.selectedMaterial.type);
const emit = defineEmits(["update", "onclick"]);

const coreStore = useCoreStore();
const itemColor = ref<string>("rgb(255,255,0)");
const showColorPicker = ref(false); // 必须重新创建，设置的color才能生效
function setColor(color: any) {
  itemColor.value = color;
  showColorPicker.value = true;
  coreStore.setColorModalVueActive(true);
}

// 设置颜色
function getChildColor(color: Color) {
  let newProps = { ...props.originalMaterial };
  newProps.color = color.toString();
  emit("update", newProps);
}

openedSubParams.value = Object.keys(props.selectedMaterial).filter((key) =>
  showChildStatus(key)
);

function showChildStatus(key: string) {
  if (key == "stiffness" && !props.selectedMaterial[key].value) return false;
  return props.selectedMaterial[key]?.hasChild === true;
}

// 回车的功能：把现在的input的type属性改成button
function showMatNameLabelHandler(key: string) {
  if (!showMatNameLabel.value) {
    showMatNameLabel.value = true;
    showedMatNameKey.value = key;
  } else {
    showMatNameLabel.value = false;
    showedMatNameKey.value = null;
  }
}
// 双击的功能：把现在的input的type属性改成text，可以输入值
function changeMatNameHandler(key: string) {
  if (showMatNameLabel.value) {
    showMatNameLabel.value = false;
    showedMatNameKey.value = null;
  } else {
    showMatNameLabel.value = true;
    showedMatNameKey.value = key;
  }
}
function getInputType(key: string, type: string) {
  return showedMatNameKey.value === key && showMatNameLabel.value
    ? type
    : "button";
}

function closeStatus(key: string) {
  // 如果key是stiffness，且value为false，不要打开子菜单
  if (key == "stiffness" && !props.selectedMaterial[key].value) return true;
  return !openedSubParams.value.includes(key);
}

function handleOpensub(key: string) {
  if (!showChildStatus(key)) return;
  if (openedSubParams.value.includes(key)) {
    openedSubParams.value = openedSubParams.value.filter(
      (item) => item !== key
    );
  } else {
    openedSubParams.value.push(key);
  }
}
function getSubKey(key: string): [string, number] {
  if (props.editorProps[key] !== undefined) return [key, 0];
  const reg = /([a-z_]+)|(\d+)/g;
  let result = key.match(reg);
  if (typeof result == "string" || result?.length === 1) return [key, 0];
  return result as [string, number];
}

function getOptions(key: string) {
  const subkey = key.split("-").at(-1) as string;
  const [trueKey, _] = getSubKey(subkey);
  if (trueKey == "material") {
    const options: { label: any; value: any }[] = [];
    props.materialListIn.forEach((item: any) => {
      if (item?.name && item?.id) {
        options.push({
          label: item.name,
          value: item.id,
        });
      }
    });
    return options;
  }
  // 对于materials要单独处理
  return getObject(key).options;
}

function getObject(key: string) {
  const subkey = key.split("-").at(-1) as string;
  const [trueKey, _] = getSubKey(subkey);
  return props.editorProps[trueKey];
}
function formatTitle(key: string) {
  const subkey = key.split("-").at(-1) as string;
  const [trueKey, num] = getSubKey(subkey);
  if (props.editorProps[trueKey] == undefined) {
    return trueKey;
  }
  return num === 0
    ? props.editorProps[trueKey].title
    : props.editorProps[trueKey].title + num;
}
function MaterialName(key: string): string {
  if (props.selectedMaterial[key]?.value !== undefined) {
    return props.selectedMaterial[key].value;
  }
  return props.selectedMaterial[key];
}
function handleChangeParam(value: any, key: string) {
  let newProps = { ...props.originalMaterial };
  if (key === "type" && previousType.value !== value) {
    let name = props.originalMaterial.name;
    let id = props.originalMaterial.id;
    let color = props.originalMaterial?.color;
    let include = props.originalMaterial?.include;
    previousType.value = value;
    newProps = { ...props.propsInitial[value] };
    newProps.name = name;
    newProps.id = id;
    if (color) newProps.color = color;
    if (include) newProps.include = include;
    newProps.type = value;
  } else {
    let keys = key.split("-");
    let temp = newProps;
    // Iterate through the keys to reach the nested property
    for (let i = 0; i < keys.length - 1; i++) {
      if (!temp[keys[i]]) {
        temp[keys[i]] = {};
      }
      temp = temp[keys[i]];
    }
    // Update the final nested property with the new value
    if (typeof temp[keys.at(-1)] === "object") {
      temp[keys.at(-1)].value = value;
    } else {
      temp[keys.at(-1)] = value;
    }
  }
  emit("update", newProps);
}
function setParamClass(key: string) {
  let len = key.split("-").length;
  return "subLevel" + len + " title" + " disable-user-select";
}
function getParamOpenStatus(key: string) {
  /**
   * @如果字段中含有hidden则隐藏
   */
  if (key.indexOf("hidden") !== -1) {
    return false;
  }
  let allKey = key.split("-");
  if (allKey.length === 1) return true;
  let tempKey = allKey[0];
  for (let i = 0; i < allKey.length; i++) {
    if (!openedSubParams.value.includes(tempKey)) return false;
    if (i === 0) continue;
    tempKey += "-" + allKey[i];
  }
  if (Object.keys(props.selectedMaterial).includes("numOfPlies")) {
    if (props.selectedMaterial["numOfPlies"].value >= 2) {
      if (allKey[1] == "material") return false;
      if (allKey[1] == "thickness") return false;
      if (allKey[1] == "theta") return false;
      if (allKey[1] == "sout") return false;
    } else if (props.selectedMaterial["numOfPlies"].value == 1) {
      if (allKey[1] == "editor") return false;
    }
  }
  return true;
}
function handleButtonClick(v: any) {
  emit("onclick", { target: v });
}
</script>
<style lang="less" scoped>
input[type="button"] {
  background-color: transparent;
  border: 0px;
  padding-left: 16px;
  outline: none;
}
.prop-row {
  width: 100%;
  background-color: white;
  padding: 2px 5px;
  box-sizing: border-box;
  font-family: PingFang SC;
  font-size: 14px;
  font-weight: 400;
  line-height: 22px;
  color: #212529;
  height: 34px;
  text-align: left;
  text-wrap: nowrap;
  > td {
    position: relative;
    width: 50%;
    line-height: 1;
    box-sizing: border-box;
    input[type="text"],
    input[type="number"] {
      width: 100%;
      text-align: left;
      order: none;
      border: none;
      outline: none;
      background: none;
      outline: 1px solid #47a4f2;
      background: #ffffff;
      height: 32px;
      padding-left: 0;
    }

    .disabled {
      padding-left: 16px;
    }

    .icon {
      display: inline-block;
      width: 14px;
      height: 14px;
      margin-right: 5px;
    }
    img {
      width: 100%;
      height: 100%;
      cursor: pointer;
    }
    .rotate {
      transform: rotate(270deg);
    }
  }
  .title {
    display: flex;
    align-items: center;
    height: 34px;
    width: 100%;
    padding: 6px 16px;
  }
  .subLevel2 {
    padding-left: 36px;
  }
  .subLevel3 {
    padding-left: 56px;
  }

  &:nth-child(even) {
    background-color: #f8f9fa;
  }
}
:deep(.vxp-select__selector) {
  border: none;
  padding: 0;
  color: #212529;
  height: 32px;
  border-radius: 2px;
  &:hover {
    outline: 1px solid #47a4f2;
  }
}
:deep(.vxp-color-picker) {
  display: block;
}
:deep(.vxp-color-picker__selector) {
  border: none;
  padding: 0;
  height: 32px;
  border-radius: 2px;
  width: 100%;
  &:hover {
    outline: 1px solid #47a4f2;
  }
}

:deep(.vxp-color-picker__selector > .vxp-color-picker__control) {
  color: #212529;
  padding-left: 16px;
}

:deep(
    .vxp-color-picker__selector
      > .vxp-color-picker__control
      > .vxp-color-picker__marker--with-label
  ) {
  width: 20px;
  height: 20px;
  min-width: 20px;
}

:deep(.vxp-select__selector > .vxp-select__control) {
  color: #212529;
}
:deep(.vxp-select__selected) {
  padding-left: 16px;
}
:deep(.vxp-checkbox__signal) {
  width: 16px;
  height: 16px;
  margin-left: 16px;
}
</style>
